/*
 * @Filename: CAN_Top.v，top module
 * @Author: ws
 * @Description: 
 * @Date: 2023-03-20 13:16:58
 * @LastEditTime: 2023-03-20 15:41:53
 * @Company: 662
 * data: PE->CAN->pe, read->240ns, write->220ns
*/

module CAN_Top(

//=========================== clk & rst ===========================//
input   wire            i_can_clk,                      // CAN_TOP clock, 125M
input   wire            i_can_rst_n,                    // i_can_clk, active low reset
input   wire            i_pe_clk,                       // PE clock, 50M
input   wire            i_pe_rst_n,                     // reset signal, low is active;

//============================== PE 50M==============================//
(*mark_debug="true"*)input   wire    [31:0]  i_addr_32b,
(*mark_debug="true"*)input   wire            i_wren,
(*mark_debug="true"*)input   wire            i_rden,
(*mark_debug="true"*)input   wire    [31:0]  i_din_32b,
(*mark_debug="true"*)output  wire             o_dout_32b_valid,
(*mark_debug="true"*)output  wire     [31:0]  o_dout_32b,
(*mark_debug="true"*)output  reg            o_interrupt,

//============================ SJA_WR =============================//
//inout   wire            can_ad,
input	wire	[7:0]	can_ad_i,			            //input address/data from SJA_1000
output	wire	[7:0]	can_ad_o,			            //output address/data to SJA_1000
output	wire		    can_ad_sel,			            //control can_ad signal direction
output  wire             can_cs_n,                       //SJA_1000 chip select input, low enable
output  wire             can_ale_as,                     //SJA_1000 address lock enable
output  wire             can_wr_n,                       //SJA_1000 write signal
output  wire             can_rd_n,                       //SJA_1000 read signal
output  wire            can_mode,                       //SJA_1000 mode select, 1->Intel mode is used
input   wire            can_int_n                      //SJA_1000 interrupt

);

/*interrupt signal control*/
//assign o_interrupt = can_int_n;
(*mark_debug="true"*)reg state_irq;
always@(posedge i_pe_clk or negedge i_pe_rst_n)begin
    if(!i_pe_rst_n)begin
        o_interrupt <= 1'b1;
        state_irq <= 1'b0;
    end
    else begin
        case(state_irq)
            1'b0:begin
                if(!can_int_n)begin
                    o_interrupt <= 1'b0;
                    state_irq <= 1'b1;
                end
                else begin
                    o_interrupt <= 1'b1;
                    state_irq <= 1'b0;
                end
            end
            1'b1:begin
                o_interrupt <= 1'b1;                                
                if(can_int_n)begin
                    state_irq <= 1'b0;
                end
                else begin
                    state_irq <= 1'b1;
                end
            end
            default:begin
                state_irq <= 1'b0;
            end
        endcase
    end
end

//wire    [7:0]   can_ad_i,can_ad_o;
//wire            can_ad_sel;
//assign can_ad = can_ad_sel? 8'bz : can_ad_o;
//assign can_ad_i = can_ad;

wire    [7:0]   soi_addr;
wire            soi_wren;
wire            soi_rden;
wire    [7:0]   soi_din;
wire    [7:0]   soi_dout;
wire            soi_dout_valid;
wire            soi_opr_end_flag;

SJA_Ctrl sja_ctrl_inst(
     .i_can_clk         (i_can_clk)
    ,.i_can_rst_n       (i_can_rst_n)
    ,.i_sys_clk         (i_pe_clk)
    ,.i_sys_rst_n       (i_pe_rst_n)

    ,.i_addr_32b        (i_addr_32b)
    ,.i_wren            (i_wren)
    ,.i_rden            (i_rden)
    ,.i_din_32b         (i_din_32b)
    ,.o_dout_32b_valid  (o_dout_32b_valid)
    ,.o_dout_32b        (o_dout_32b)

    ,.o_soi_addr        (soi_addr)
    ,.o_soi_wren        (soi_wren)
    ,.o_soi_rden        (soi_rden)
    ,.o_soi_din         (soi_din)
    ,.i_soi_dout        (soi_dout)
    ,.i_soi_dout_valid  (soi_dout_valid)
    ,.i_soi_opr_end_flag(soi_opr_end_flag)
);


SJA_WR sja_wr_inst(
     .i_can_clk         (i_can_clk)
    ,.i_can_rst_n       (i_can_rst_n)

    ,.can_ad_i          (can_ad_i)
    ,.can_ad_o          (can_ad_o)
    ,.can_ad_sel        (can_ad_sel)
    ,.can_cs_n          (can_cs_n)
    ,.can_ale_as        (can_ale_as)
    ,.can_wr_n          (can_wr_n)
    ,.can_rd_n          (can_rd_n)
    ,.can_mode          (can_mode)
    //,.can_int_n         (can_int_n)

    ,.i_soi_addr        (soi_addr)
    ,.i_soi_wren        (soi_wren)
    ,.i_soi_rden        (soi_rden)
    ,.i_soi_din         (soi_din)
    ,.o_soi_dout        (soi_dout)
    ,.o_soi_dout_valid  (soi_dout_valid)
    ,.o_soi_opr_end_flag(soi_opr_end_flag)
);

endmodule
